﻿using Microsoft.EntityFrameworkCore;
using Quickly.Certs.Core;

namespace Quickly.Certs.EntityFrameworkCore.Data
{
    public class DomainNameStore : IDomainNameStore
    {
        protected virtual CertsContext Context { get; set; }

        public DomainNameStore(CertsContext context)
        {
            Context = context;
        }

        public async Task<List<string>> LoadAsync(CancellationToken cancellationToken)
        {
            var query = Context.DomainNames.AsNoTracking()
                .Select(x => x.Name);

            return await query.ToListAsync(cancellationToken);
        }

        public async Task SaveAsync(List<string> domainNames, long certFileId, CancellationToken cancellationToken)
        {
            var entities = await Context.DomainNames
                .Where(x => domainNames.Contains(x.Name))
                .ToListAsync(cancellationToken);

            var dict = entities.GroupBy(x => x.Name)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault()!);

            foreach (var domainName in domainNames)
            {
                if (dict.TryGetValue(domainName, out var found))
                {
                    found.CertificateId = certFileId;
                    found.LastModified = DateTimeOffset.UtcNow;
                }
                else
                {
                    Context.Add(new DomainName
                    {
                        Name = domainName,
                        Created = DateTimeOffset.UtcNow,
                        LastModified = DateTimeOffset.UtcNow,
                        CertificateId = certFileId
                    });
                }
            }

            await Context.SaveChangesAsync(cancellationToken);
        }

        public async Task<List<long>> LoadCertificateIdsAsync(CancellationToken cancellationToken)
        {
            return await Context.DomainNames
                .Select(x => x.CertificateId)
                .Distinct()
                .ToListAsync(cancellationToken);
        }

        public async Task<List<long>> GetCertificateIdsAsync(List<string> dnsNames, CancellationToken cancellationToken)
        {
            return await Context.DomainNames
                .AsNoTracking()
                .Select(x => x.CertificateId)
                .Distinct()
                .ToListAsync(cancellationToken);
        }
    }
}
